#!/usr/bin/env python
# coding: utf-8

class Bookmarkitem():
    def __init__(self, title, page, parent=None, level= 0):
        self.parent = parent
        self.children = []
        self.title = title
        self.page = page
        self.level = level
        
    def add_child(self, child):
        self.children.append(child)
        child.parent = self
    
    def page_tree_inc(self, inc):
        self.page = self.page + inc
        if len(self.children) == 0:
            return
        else:
            for child in self.children:
                child.page_tree_inc(inc)
    def show(self, level=0):
        print('\t'*level + f'{self.title}\t{self.page}')
        if self.children:
            for child in self.children:
                child.show(level+1)

    def to_list(self):
        result = [(self.level, self.title, self.page)]
        for child in self.children:
            result.extend(child.to_list())
        return result
        
    def get_str(self, level=0):
        s = []
        l = '\t'*level + f'{self.title}\t{self.page}'
        s.append(l)
        for child in self.children:
            s.extend(child.get_str(level+1))
        return s
    def __str__(self):
        return '\n'.join(self.get_str())


class Bookmark():
    def __init__(self):
        self.roots = []
        self.current = None
        self.parent_stack = []
        self.op_level = 0   # operating level
        return
    def add_line(self, line):
        level, title, page = self.parse(line)
        self.add_item(level, title, page)
        
    def get_parent(self): 
        if len(self.parent_stack) == 0:
            return None
        return self.parent_stack[-1]
    
    def add_item(self, level, title, page):
        def add_child(newitem):
            if parent:
                parent.add_child(newitem)
            else:
                self.roots.append(newitem)
        level = level if level>0 else 0  # level should be greater or equal to 0
        newitem = Bookmarkitem(title, page, level=level)  # add a level info for reference
        if level == self.op_level:      # operate at the same level
            parent = self.get_parent()  # so they share the save parent
            add_child(newitem)
        elif level < self.op_level:
            for i in range(self.op_level-level):
                if self.parent_stack:
                    self.parent_stack.pop()
                else:
                    break
            parent = self.get_parent()
            add_child(newitem)
            #print(level)
            self.op_level = level
        elif level > self.op_level:  # operating a child
            parent = self.current
            if not parent: # for empty bookmark
                dummy = self.make_dummpy_parent()
                add_child(dummy)
                parent = dummy
            for i in range(self.op_level, level):
                self.parent_stack.append(parent)
                if i != level-1:
                    print(f'make dumpy at level {i}')
                    dummy = self.make_dummpy_parent()
                    add_child(dummy)
                    parent = dummy
            add_child(newitem)
            self.op_level = level
        self.current = newitem
    
    def make_dummpy_parent(self):
        return Bookmarkitem('dummpy', 0)
        
    @staticmethod
    def parse(line):
        # root == level 0
        level = 0
        # every tab in the begining adds one level to the current line
        for x in line:
            if x == '\t':
                level += 1
            else:
                break
        data = line[level:].split('\t') # the title and the page are seperated by a tab
        if len(data) >= 2:
            title, page = data[0:2]
        else:
            title, page = data[0], 0 # if there is no page info
        return level, title, int(page)
    def show(self):
        for root in self.roots:
            root.show()
    def __str__(self):
        s = []
        for root in self.roots:
            s.append(str(root))
        return '\n'.join(s)
